﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Security.Cryptography;

namespace WorkStation.Frameworks.Core.Extensions
{
    /// <summary>
    /// * 扩展string类
    /// </summary>
    public static class StringExtensions
    {
        /// <summary>
        /// * 判断文本是否为数字类型
        /// </summary>
        /// <param name="sText"></param>
        /// <returns></returns>
        public static bool IsNumber(this string sText)
        {
            if (!Regex.IsMatch(sText, @"^(-?\d+)(\.\d+)?$"))
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// * 判断文本是否为整数
        /// </summary>
        /// <param name="sText"></param>
        /// <returns></returns>
        public static bool IsInteger(this string sText)
        {
            if (Regex.IsMatch(sText, @"^-?\d+$"))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// * 判断是否为Email地址
        /// </summary>
        /// <param name="sText"></param>
        /// <returns></returns>
        public static bool IsEmail(this string sText)
        {
            if (Regex.IsMatch(sText, @"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// * 字符串对称DES加密
        /// </summary>
        /// <param name="sText"></param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public static string DESEncrypt(this string sText, string key, string iv)
        {
            string res = "";

            MemoryStream mStream = null;
            CryptoStream cStream = null;
            StreamWriter sWriter = null;

            #region * 检查Key的长度, 不足8位补足, 超出的截取

            if (key.Length != 8)
            {
                if (key.Length < 8)
                {
                    string temp = "";

                    for (int i = 0; i < 8 - key.Length; i++)
                    {
                        temp += "X";
                    }

                    key = key + temp;
                }

                if (key.Length > 8)
                {
                    key = key.Substring(0, 8);
                }
            }

            #endregion

            #region * 检查IV的长度, 不足8位补足, 超出截取

            if (iv.Length != 8)
            {
                if (iv.Length != 8)
                {
                    if (iv.Length < 8)
                    {
                        string temp = "";

                        for (int i = 0; i < 8 - iv.Length; i++)
                        {
                            temp += "X";
                        }

                        iv = iv + temp;
                    }

                    if (iv.Length > 8)
                    {
                        iv = iv.Substring(0, 8);
                    }
                }
            }

            #endregion

            try
            {
                DESCryptoServiceProvider provider = new DESCryptoServiceProvider();

                mStream = new MemoryStream();
                cStream = new CryptoStream(mStream, provider.CreateEncryptor(key.ToBytesByASCII(), iv.ToBytesByASCII()), CryptoStreamMode.Write);
                sWriter = new StreamWriter(cStream);

                sWriter.Write(sText);
                sWriter.Flush();
                cStream.FlushFinalBlock();

                res = Convert.ToBase64String(mStream.GetBuffer(), 0, Convert.ToInt32(mStream.Length));
            }
            catch (Exception ce)
            {
                throw;
            }
            finally
            {
                if (sWriter != null) { sWriter.Flush(); sWriter.Close(); }
                if (cStream != null) { cStream.Flush(); cStream.Close(); }
                if (mStream != null) { mStream.Flush(); mStream.Close(); }
            }

            return res;
        }

        /// <summary>
        /// * 字符串对称DES加密
        /// </summary>
        /// <param name="sText"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string DESEncrypt(this string sText, string key)
        {
            return sText.DESEncrypt(key, "12345678");
        }

        /// <summary>
        /// * 字符串对称DES解密
        /// </summary>
        /// <param name="sText"></param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public static string DESDecrypt(this string sText, string key, string iv)
        {
            string res = "";

            MemoryStream mStream = null;
            CryptoStream cStream = null;
            StreamReader sReader = null;

            #region * 检查Key的长度, 不足8位补足, 超出的截取

            if (key.Length != 8)
            {
                if (key.Length < 8)
                {
                    string temp = "";

                    for (int i = 0; i < 8 - key.Length; i++)
                    {
                        temp += "X";
                    }

                    key = key + temp;
                }

                if (key.Length > 8)
                {
                    key = key.Substring(0, 8);
                }
            }

            #endregion

            #region * 检查IV的长度, 不足8位补足, 超出截取

            if (iv.Length != 8)
            {
                if (iv.Length != 8)
                {
                    if (iv.Length < 8)
                    {
                        string temp = "";

                        for (int i = 0; i < 8 - iv.Length; i++)
                        {
                            temp += "X";
                        }

                        iv = iv + temp;
                    }

                    if (iv.Length > 8)
                    {
                        iv = iv.Substring(0, 8);
                    }
                }
            }

            #endregion

            try
            {
                DESCryptoServiceProvider provider = new DESCryptoServiceProvider();

                mStream = new MemoryStream(Convert.FromBase64String(sText));
                cStream = new CryptoStream(mStream, provider.CreateDecryptor(key.ToBytesByASCII(), iv.ToBytesByASCII()), CryptoStreamMode.Read);
                sReader = new StreamReader(cStream);

                res = sReader.ReadToEnd();
            }
            catch (Exception ce)
            {
                throw;
            }
            finally
            {
                if (sReader != null) { sReader.Close(); }
                if (cStream != null) { cStream.Flush(); cStream.Close(); }
                if (mStream != null) { mStream.Flush(); mStream.Close(); }
            }

            return res;
        }

        /// <summary>
        /// * 字符串对称DES解密
        /// </summary>
        /// <param name="sText"></param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public static string DESDecrypt(this string sText, string key)
        {
            return sText.DESDecrypt(key, "12345678");
        }

        /// <summary>
        /// * 将字符串转为字节数组
        /// </summary>
        /// <param name="sText"></param>
        /// <returns></returns>
        public static byte[] ToBytesByASCII(this string sText)
        {
            return ASCIIEncoding.ASCII.GetBytes(sText);
        }

        /// <summary>
        /// 将字符串转为字节数组 编码UTF8
        /// </summary>
        /// <param name="sText"></param>
        /// <returns></returns>
        public static byte[] ToBytesByUTF8(this string sText) 
        {
            return Encoding.UTF8.GetBytes(sText);
        }

        #region * 常量（全角半角转换）

        // 最大的有效全角英文字符转换成int型数据的值
        private const int MaxSBCcaseToInt = 65374;
        // 最小的有效全角英文字符转换成int型数据的值
        private const int MinSBCcaseToInt = 65281;

        // 最大的有效半角英文字符转换成int型数据的值
        private const int MaxDBCcaseToInt = 126;
        // 最小的有效半角英文字符转换成int型数据的值
        private const int MinDBCcaseToInt = 33;

        private const int SBCBlankToInt = 12288;
        private const int DBCBlankToInt = 32;

        // 对应的全角和半角的差
        private const int Margin = 65248;

        #endregion

        /// <summary>
        /// * 全角字符串转半角
        /// </summary>
        /// <param name="sText"></param>
        /// <returns></returns>
        public static string ToDBC(this string sText)
        {
            char[] res = sText.ToCharArray();

            for (int i = 0; i < res.Length; i++)
            {
                if (res[i] == 12288)
                {
                    res[i] = Convert.ToChar(32);
                    continue;
                }

                if (res[i] >= MinSBCcaseToInt && res[i] <= MaxSBCcaseToInt)
                {
                    res[i] = Convert.ToChar(res[i] - Margin);
                }
            }

            return new string(res);
        }

        /// <summary>
        /// * JSON转换为实体
        /// </summary>
        /// <typeparam name="TObject">实体类型</typeparam>
        /// <param name="sText"></param>
        /// <returns></returns>
        public static TObject JsonToObject<TObject>(this string sText) 
        {
            return Json.JsonHelper.ToObject<TObject>(sText);
        }

        /// <summary>
        /// 格式化字符串
        /// </summary>
        /// <param name="text">字符串</param>
        /// <param name="objs">填充字符串</param>
        /// <returns></returns>
        public static string Fmt(this string text, params object[] objs) 
        {
            if (objs == null)
            {
                return string.Format(text, string.Empty);
            }

            return string.Format(text, objs);
        }

        /// <summary>
        /// 字符串是否为空
        /// </summary>
        /// <param name="text">字符串</param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this string text) 
        {
            return string.IsNullOrEmpty(text);
        }

        /// <summary>
        /// 字符串是否为空或空格
        /// </summary>
        /// <param name="text">字符串</param>
        /// <returns></returns>
        public static bool IsNullOrWhiteSpace(this string text) 
        {
            return string.IsNullOrWhiteSpace(text);
        }
    }
}
